/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

extern crate alloc;

use crate::Vec;
use alloc::boxed::Box;

use crate::common::constants::*;
use crate::entry::user_auth_ffi::CommandId;
use crate::log_e;
use crate::traits::command_manager::{CommandHandler, CommandManager};

pub struct DefaultCommandManager {
    command_handlers: Vec<Box<dyn CommandHandler>>,
}

impl DefaultCommandManager {
    pub fn new() -> Self {
        Self {
            command_handlers: Vec::new(),
        }
    }
}

impl CommandManager for DefaultCommandManager {
    fn register(&mut self, command: Box<dyn CommandHandler>) -> Result<(), ErrorCode> {
        // Check if command with same ID already exists
        if self.get(*command.command_id()).is_ok() {
            log_e!(
                "Command with ID {:?} already registered",
                command.command_id()
            );
            return Err(ErrorCode::BadParam);
        }

        // Add the command handler
        self.command_handlers.push(command);
        Ok(())
    }

    fn get(&self, command_id: CommandId) -> Result<&Box<dyn CommandHandler>, ErrorCode> {
        self.command_handlers
            .iter()
            .find(|h| h.command_id() == &command_id)
            .ok_or(ErrorCode::NotFound)
    }
}
